<?php
class ControllerExtensionOauthWechatPc extends Controller
{

    const EXTENSION_GROUP = 'oauth';

    const EXTENSION_TYPE = 'wechat_pc';

    const SETTING_CODE = self::EXTENSION_GROUP . '_' . self::EXTENSION_TYPE;

	public function loginAction()
    {
        $this->load->language('extension/oauth/wechat_pc');
        $setting = $this->model_setting_setting->getSetting(self::SETTING_CODE);

		return [
            'type'  => 'wechat_pc',
            'title'  => $this->language->get('text_title'),
            /**
             * @see https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316505&token=33795fca9b8615ad59fca9828fe7d0e2a9de9ec4&lang=zh_CN
             */
            'action' => 'https://open.weixin.qq.com/connect/qrconnect?' . http_build_query([
                    'appid'         => $this->config->get('oauth_wechat_pc_app_id'),
                    'response_type' => 'code',
                    'scope'         => 'snsapi_login',
                    'redirect_uri'  => $this->url->link('account/login/oauthCallback') . '&type=wechat_pc',
                    'state'         => 'pc_oauth_login', // 非必填
            ]) . '#wechat_redirect' ,   // 在外面拼接 . '&type=wechat_pc' 防止 & 被转成 &amp;

            'sort_order' => $this->config->get('oauth_wechat_pc_sort_order'),

            'icon' => image_resize($setting[self::SETTING_CODE. '_icon'])
        ];
	}

    /**
     * @link https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419316518&token=33795fca9b8615ad59fca9828fe7d0e2a9de9ec4&lang=zh_CN
     *     - 文档
     * @throws Exception
     */
    public function callback()
    {
        $token_data = $this->queryAccessToken();
        $user_data = $this->queryUserData($token_data);
        $user_data = $this->normalizeUserData($user_data);
        $oauthUser = $this->updateOrCreateUser($user_data);

        $customer_id = (int) $oauthUser['customer_id'];
        if ($customer_id) {
            $this->customer->loginByCustomerId($customer_id); // 改成 customer

            return $this->url->link('account/login/oauthSuccess');
        } else {
            $query = http_build_query([
                'oauth_type'    => 'wechat_pc',
                'oauth_user_id' => $oauthUser['wechat_user_id'],
            ]);

            return $this->url->link('account/register', $query);
        }
	}

    /**
     * @param $user_info
     *
     * @return array
     * @throws Exception
     */
    protected function updateOrCreateUser($user_info)
    {
        /** @var ModelExtensionOauthWechatUser $modelUser */
        $modelUser = $this->loadModel('extension/oauth/wechat_user');

        $user = $modelUser->updateOrCreateUserInfo($user_info);

        return $user;
    }

    /**
     * @return bool
     *
     * @throws Exception
     */
    public function bindCustomer()
    {
        /** @var ModelExtensionOauthWechatUser $modelOauthUser */
        $modelOauthUser = $this->loadModel('extension/oauth/wechat_user');

        $modelOauthUser->bindCustomer($this->customer->getId(), $this->requestGet('oauth_user_id'));

        return true;
    }

    /**
     * @param $user_data
     *
     * @return array
     */
    protected function normalizeUserData($user_data): array
    {
        $user_data = array_only($user_data, [
                'openid', 'nickname', 'sex', 'province', 'city',
                'country', 'headimgurl', 'unionid'
            ]) + [
                'nickname_unicode' => json_encode($user_data['nickname'])
            ];

        return $user_data;
}

    /**
     * @param $token_data
     *
     * @return mixed
     */
    protected function queryUserData($token_data)
    {
        $user_info_api = 'https://api.weixin.qq.com/sns/userinfo?' . http_build_query([
                'openid'       => $token_data['openid'],
                'access_token' => $token_data['access_token'],
            ]);

        /**
         * [
         * "openid":"OPENID",
         * "nickname":"NICKNAME",
         * "sex":1,
         * "province":"PROVINCE",
         * "city":"CITY",
         * "country":"COUNTRY",
         * "headimgurl": "http://wx.qlogo.cn/mmopen/g3Mon..",
         * "privilege":[
         * "chinaunicom",
         * ],
         * "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
         * ]
         */
        $user_data = json_decode(file_get_contents($user_info_api), true);
        if (isset($user_data['errcode'])) {
            $msg = $user_data['errmsg'];
            $code = $user_data['errcode'];
            $this->jsonError("授权发生错误, $msg($code)");
        }

        return $user_data;
}

    /**
     * @return mixed
     */
    protected function queryAccessToken()
    {
        $token_api = 'https://api.weixin.qq.com/sns/oauth2/access_token?' . http_build_query([
                'appid'      => $this->config->get('oauth_wechat_pc_app_id'),
                'secret'     => $this->config->get('oauth_wechat_pc_app_secret'),
                'code'       => $this->requestAny('code'),
                'grant_type' => 'authorization_code',
            ]);


        /**
        $res = [
            'access_token'  => '17_vFrec7jupU-5E_JZNBPHx2Khfdy5ZAx3PC6LkBZtZi2JFyoHGMzzKIXMAu48M_VzhFsMaF3R9WbdF2tc77cWjA',
            'expires_in'    => 7200,
            'refresh_token' => '17_u1RWS5NGYRRTKt844hQHs5kuqv1M4rSpRvnBe6zpdSb6O-cleRly_wKgaJNrBILvSoUQ-80TfhoAdZitGm3ShA',
            'openid'        => 'oMG9g5l1cufYV593aq0Veq3aqH2g',
            'scope'         => 'snsapi_login',
            'unionid'       => 'oPqJDs1edysW4GJbQ0VyScJHD_0c',
            ];
         */
        $token_data = json_decode(file_get_contents($token_api), true);

        if (isset($token_data['errcode'])) {
            $msg = $token_data['errmsg'];
            $code = $token_data['errcode'];
            $this->jsonError("授权发生错误, $msg($code)");
        }

        return $token_data;
    }
}